package com.itita.ww2.core;

import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 计时器任务,处理时间类任务
 * 时间比对由外部传入(interface)
 * @author NorthLan
 *
 */
public class TaskPerSecond implements Runnable {
	// 任务列表
	private static ConcurrentHashMap<String, TaskBean> tasks = new ConcurrentHashMap<>();
	private ExecutorService pool;

	public TaskPerSecond() {
		pool = Executors.newSingleThreadExecutor();
	}

	@Override
	public void run() {
		// 满足时间条件,开启线程来执行对应的runnable,执行时即刻将其从任务列表中移除
		for (Entry<String, TaskBean> taskMap : tasks.entrySet()) {
			TaskBean task = taskMap.getValue();
			if (task == null) {
				continue;
			}
			if (task.conn.condition()) {
				pool.execute(task.run);
				// task.run.run();
				if (task.autoRemove) {
					removeTask(taskMap.getKey());
				}
			}
		}
	}
	
	public static ConcurrentHashMap<String, TaskBean> getTasks(){
		return tasks;
	}

	public static void addTask(String key, ITimerCondition condition, Runnable runable, boolean autoRemove) {
		tasks.put(key, new TaskBean(condition, runable, autoRemove));
	}

	public static void addTask(String key, Runnable runable, int delay, int period) {
		ITimerCondition conn = new ITimerCondition() {
			private int count = 0;
			private boolean first = true;

			@Override
			public boolean condition() {
				if (first) {
					if (count == delay) {
						count = 0;
						first = false;
						return true;
					} else {
						count++;
						return false;
					}
				} else {
					if (count == period) {
						count = 0;
						return true;
					} else {
						count++;
						return false;
					}
				}
			}
		};
		addTask(key, conn, runable, false);
	}

	public static Runnable removeTask(String key) {
		if (tasks.containsKey(key)) {
			return tasks.remove(key).run;
		}
		return null;
	}

	/**
	 * 移除任务并且在移除之前执行一次
	 */
	public static void removeAndRun(String key) {
		if (tasks.containsKey(key)) {
			tasks.remove(key).run.run();
		}
	}

	public static class TaskBean {
		public ITimerCondition conn;
		public Runnable run;
		public boolean autoRemove;

		public TaskBean(ITimerCondition conn, Runnable run, boolean autoRemove) {
			this.conn = conn;
			this.run = run;
			this.autoRemove = autoRemove;
		}
	}

	public static interface ITimerCondition {
		public int count = 0;
		public boolean first = true;

		public boolean condition();
	}

}
